package com.bamboo.custom.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.Shader;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.ColorRes;

import com.bamboo.custom.R;

import java.util.ArrayList;
import java.util.List;

/**
 * 项目名称：
 *
 * @Author bamboolife
 * 创建时间：2021/9/9 2:08 下午
 * 描述：自定义分钟降水折线图
 */
public class LineCharView extends View {
    //变量增量
    private float mDeltaX;
    private float mDeltaY;
    //最终值
    private int mFinalX;
    private int mFinalY;
    //xy最大最小值
    private int mMinX;
    private int mMaxX;
    private int mMinY;
    private int mMaxY;
    //当前值
    private int mCurrX;
    private int mCurrY;

    //坐标原始点
    private int originX;
    private int originY;

    //设置默认间距
    private int marginDefault = dip2px(16);
    //CharView四周间距
    private int marginStart = marginDefault;
    private int marginEnd = marginDefault;
    private int marginTop = marginDefault;
    private int marginBottom = dip2px(40);


    //折线数据
    private List<Float> lineDates = new ArrayList<>();
    //网格线画笔
    private Paint paintGridLine;
    private int lineWidth;
    private int gridLineColor;  //网格线的颜色
    //x轴画笔
    private Paint paintAxisX;
    private int xAxisColor;  //x轴的颜色
    private int xLineWidth;

    private Paint paintFill;
    private TextPaint mTextPaint;
    private int textColor;
    private float textSize;
    private String yText = "大";
    private float mTextWidth;
    private float mTextHeight;

    private Paint paintLine;

    //控件的宽和高
    private int width;
    private int height;
    //垂直和水平间隔
    private float intervalX;
    private float intervalY;
    //x轴的开始点和结束点
    private float startX;
    private float startY;
    private float endX;
    private float endY;
    //x轴左右边界
    private int leftBorder = dip2px(30);
    private int rightBorder = leftBorder;
    //文字开始
    private float startTextY;
    //刻度的高度
    private int scaleHeight = dip2px(10);

    private List<String> yValues = new ArrayList<>();
    private List<String> xValues = new ArrayList<>();

    public LineCharView(Context context) {
        super(context);
        init(null, 0);
    }

    public LineCharView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public LineCharView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, defStyle);

    }


    private void init(AttributeSet attrs, int defStyle) {
        final TypedArray a = getContext().obtainStyledAttributes(
                attrs, R.styleable.LineCharView, defStyle, 0);
        textColor = a.getColor(R.styleable.LineCharView_CharTextColor, Color.parseColor("#25262B"));
        textSize = a.getDimension(R.styleable.LineCharView_charTextSize, sp2px(9));
        lineWidth = a.getDimensionPixelSize(R.styleable.LineCharView_CharLineWidth, dip2px(1));
        xLineWidth = a.getDimensionPixelSize(R.styleable.LineCharView_CharXLineWidth, dip2px(2));
        gridLineColor = a.getColor(R.styleable.LineCharView_CharLineColor, Color.parseColor("#DEEAFD"));
        xAxisColor = a.getColor(R.styleable.LineCharView_CharAxisColor, Color.parseColor("#b4c7eb"));
        a.recycle();
        initPaint();

    }

    private void initPaint() {
        mTextPaint = new TextPaint();
        mTextPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setTextAlign(Paint.Align.LEFT);
        invalidateTextPaintAndMeasurements();

        paintGridLine = new Paint();
        paintGridLine.setStyle(Paint.Style.STROKE);
        paintGridLine.setStrokeWidth(lineWidth);
        paintGridLine.setColor(gridLineColor);

        paintAxisX = new Paint();
        paintAxisX.setStyle(Paint.Style.STROKE);
        paintAxisX.setStrokeWidth(xLineWidth);
        paintAxisX.setColor(xAxisColor);

        paintLine = new Paint();
        paintLine.setStyle(Paint.Style.STROKE);
        paintLine.setStrokeWidth(dip2px(2));
        paintLine.setDither(true);
        paintLine.setColor(Color.parseColor("#437EDE"));

        paintFill = new Paint();
        paintFill.setColor(Color.parseColor("#ff437ede"));
        paintFill.setStrokeWidth(2f);
        paintFill.setStyle(Paint.Style.FILL);


    }

    private void invalidateTextPaintAndMeasurements() {
        mTextPaint.setTextSize(textSize);
        mTextPaint.setColor(textColor);
        mTextWidth = mTextPaint.measureText(yText);

        Paint.FontMetrics fm = mTextPaint.getFontMetrics();
        mTextHeight = fm.bottom + fm.leading;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 宽度的模式
        int widthModel = MeasureSpec.getMode(widthMeasureSpec);
        //宽度大小
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        //高度模式
        int heightModel = MeasureSpec.getMode(heightMeasureSpec);
        //高度大小
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        //如果明确了宽度大小，直接设置大小
        if (widthModel == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {
            //计算宽度，可以根据实际情况进行计算。
            width = (getPaddingStart() + getPaddingRight());
            //如果为AT_MOST, 不允许超过默认宽度的大小
            if (widthModel == MeasureSpec.AT_MOST) {
                width = Math.min(width, widthSize);
            }
        }

        if (heightModel == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else {
            height = getPaddingTop() - getPaddingBottom();
            if (heightModel == MeasureSpec.AT_MOST) {
                height = Math.min(height, heightSize);
            }
        }

        //设置测量好的宽和高
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        originX = marginStart;
        originY = height - marginTop - marginBottom;
        if (yValues.size() > 0) {
            intervalY = (height - marginTop - marginBottom) / yValues.size();
        }
        startTextY = intervalY / 2f + marginTop + dip2px(2);
        startX = originX + leftBorder;
        startY = marginTop + intervalY * 3;
        endX = width - marginEnd - rightBorder;
        endY = startY;
        intervalX = (endX - startX) / 119f;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (yValues.size() > 0) {
            drawGradLine(canvas, paintGridLine);
        }
        drawXAxis(canvas, paintAxisX);
        drawYText(canvas, mTextPaint);
        drawXScale(canvas, paintAxisX);
        if (xValues.size() > 0) {
            drawXText(canvas, mTextPaint);
        }
        if (lineDates.size() > 0) {
            drawBrokenLine(canvas, paintLine);
        }
    }


    /**
     * 画网格
     *
     * @param canvas
     * @param paint
     */
    private void drawGradLine(Canvas canvas, Paint paint) {
        for (int i = 0; i <= yValues.size(); i++) {
            canvas.drawLine(marginStart, marginTop + intervalY * i, width - marginEnd, intervalY * i + marginTop, paint);
        }
    }


    /**
     * 画Y轴的文字
     *
     * @param canvas
     * @param paint
     */
    private void drawYText(Canvas canvas, Paint paint) {
        for (int i = 0; i < yValues.size(); i++) {
            canvas.drawText(yValues.get(i), marginStart, startTextY + intervalY * i, paint);
        }
    }

    /**
     * 画x轴刻度
     *
     * @param canvas
     * @param paint
     */
    private void drawXScale(Canvas canvas, Paint paint) {
        //开始刻度
        canvas.drawLine(startX, startY, startX, startY + scaleHeight, paint);
        //中间刻度
        float center = (endX - startX) / 2 + startX;
        canvas.drawLine(center, startY, center, startY + scaleHeight, paint);
        //结束刻度
        canvas.drawLine(endX, endY, endX, endY + scaleHeight, paint);
    }

    /**
     * 画x轴上的文字
     *
     * @param canvas
     * @param paint
     */
    private void drawXText(Canvas canvas, Paint paint) {
        canvas.drawText(xValues.get(0), startX - dip2px(10), startY + scaleHeight * 2.5f, paint);
        float center = (endX - startX) / 2 + startX;
        canvas.drawText(xValues.get(1), center - dip2px(16), startY + scaleHeight * 2.5f, paint);
        canvas.drawText(xValues.get(2), endX - dip2px(16), startY + scaleHeight * 2.5f, paint);

    }

    /**
     * 画x轴
     *
     * @param canvas
     * @param paint
     */
    private void drawXAxis(Canvas canvas, Paint paint) {
        canvas.drawLine(startX, endY - dip2px(0.15f), endX, endY - dip2px(0.15f), paint);
    }

    private void drawBrokenLine(Canvas canvas, Paint paint) {
        float maxHeght = lineDates.get(0);
        Float oneValue = lineDates.get(0);
        Path path = new Path();
        Path filPath = new Path();
        for (int i = 0; i < lineDates.size(); i++) {
            float tempHeight = 0;
            if (0f < oneValue && oneValue <= 0.3f) {
                tempHeight = lineDates.get(i) / 0.3f * intervalY;
            } else if (oneValue > 0.3f && oneValue <= 0.5f) {
                tempHeight = (lineDates.get(i) - 0.3f) / (0.5f - 0.3f) * intervalY + intervalY;
            } else if (oneValue > 0.5f && oneValue <= 1.0f) {
                tempHeight = (lineDates.get(i) - 0.5f) / (1.0f - 0.5f) * intervalY + intervalY + intervalY;
            }
            float y = startY - tempHeight;
//            Log.i("log_h", "interval1: "+((lineDates.get(i)-0.5f) /(1f-0.5f) ));
//            Log.i("log_h", "intervalY: "+intervalY);
//            Log.i("log_h", "drawBrokenLine: "+lineDates.get(i));
//            Log.d("log_h", "drawBrokenLine:tempHeight= "+tempHeight);
//            Log.d("log_h", "drawBrokenLine:y= "+y);
//            Log.d("log_h", "drawBrokenLine:startY="+startY);
//            Log.d("log_h", "drawBrokenLine:top="+marginTop);
            if (y < maxHeght) {
                maxHeght = y;

            }
            // Log.i("log_size", "drawBrokenLine: "+maxHeght);
            if (i == 0) {
                path.moveTo(startX, y);
                filPath.moveTo(startX, y);
            } else {
                path.lineTo(startX + i * intervalX, y);
                filPath.lineTo(startX + i * intervalX, y);
                if (i == lineDates.size() - 1) {
                    filPath.lineTo(endX, endY);
                    filPath.lineTo(startX, startY);
                    filPath.close();
                }
            }
        }
        //这里的值越大，折角处的圆角就越光滑
        CornerPathEffect mPathEffect = new CornerPathEffect(50);
        paint.setPathEffect(mPathEffect);

        canvas.drawPath(path, paint);
        LinearGradient linearGradient = new LinearGradient(startX, maxHeght, startX, startY, Color.parseColor("#ff437ede"), Color.parseColor("#60DDE9FD"), Shader.TileMode.CLAMP);
        paintFill.setShader(linearGradient);
        paintFill.setPathEffect(mPathEffect);
        canvas.drawPath(filPath, paintFill);
    }

    /**
     * 设置文字的颜色
     *
     * @param color
     */
    public void setTextColor(@ColorRes int color) {
        this.textColor = color;
        invalidateTextPaintAndMeasurements();
    }

    /**
     * 设置文字大小
     *
     * @param textSize
     */
    public void setTextSize(float textSize) {
        this.textSize = textSize;
        invalidateTextPaintAndMeasurements();
    }

    /**
     * 设置Y轴的值
     *
     * @param yValues
     */
    public void setYText(List<String> yValues) {
        this.yValues = yValues;
    }

    /**
     * 设置x轴的值
     *
     * @param xValues
     */
    public void setXText(List<String> xValues) {
        this.xValues = xValues;
    }

    public void setLineDates(List<Float> lineDates) {
        this.lineDates = lineDates;
    }

    public void refreshUI() {
        invalidate();
    }

    private int dip2px(int dp) {
        float density = getContext().getResources().getDisplayMetrics().density;
        return (int) (dp * density + 0.5);
    }

    private int dip2px(float dp) {
        float density = getContext().getResources().getDisplayMetrics().density;
        return (int) (dp * density + 0.5);
    }

    /**
     * sp转换px
     */
    private int sp2px(int spValue) {
        final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }
}